package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.DepositRefundDTO;
import com.sc.nft.entity.dto.MallDeductMoneyDto;
import com.sc.nft.entity.dto.MarginPaymentDTO;
import com.sc.nft.entity.dto.OperateUserWalletBatchAmountDTO;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.pool.UserPool;
import com.sc.nft.service.UserWalletService;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 用户钱包表服务接口实现
 *
 * @author kancy
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2022-08-18 01:22:40
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserWalletServiceImpl implements UserWalletService {

    private final UserWalletDao userWalletDao;
    private final UserWalletDetailDao userWalletDetailDao;
    private final ExpenditureRecordDao expenditureRecordDao;

    private final Redisson redisson;

    private final UserInfoDao userInfoDao;

    private final StaticDataDao staticDataDao;

    private final UserBankCardDao userBankCardDao;

    private final DepositWithdrawalRecordDao depositWithdrawalRecordDao;

    private final HfFastBankDao hfFastBankDao;

    private final LlUserExtDao llUserExtDao;
    private final MetaMapSettleDao metaMapSettleDao;

    @Override
    public UserWallet getByUserId(Long userId) {
        return userWalletDao.getByUserId(userId);
    }

    @Override
    public UserWalletVO getByUser(UserInfo user, String type) {
        if (type.equals(UserWalletEnum.PLATFORM_WALLET.getDescription())) {
            throw new GlobalRunTimeException("钱包类型不正确");
        }
        String isRecharge = staticDataDao.getByType("is_recharge").getValue();
        String isWithdraw = staticDataDao.getByType("is_withdraw").getValue();

        UserWallet userWallet = userWalletDao.getByUserId(user.getId());
        UserWalletVO userWalletVO = BeanUtil.copyProperties(userWallet, UserWalletVO.class);
        userWalletVO.setUserBankCount(userBankCardDao.getCountByUserId(user.getId()));
        userWalletVO.setHfUserBankCount(hfFastBankDao.getCountByUserId(user.getId()));
        userWalletVO.setWithdrawBalance(userWallet.getBalance().setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setRedEnvelope(userWallet.getPayBalance().setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setWishBalance(userWallet.getWishBalance().setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setBalance(userWallet.getBalance().add(userWallet.getPayBalance()).setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setIsSm(user.getIsSm());
        userWalletVO.setUserTel(user.getUserTel());
        userWalletVO.setName("钱包A");
        userWalletVO.setIsEnable(Boolean.TRUE);
        userWalletVO.setType(UserWalletEnum.PLATFORM_WALLET);
        userWalletVO.setIsRecharge(isRecharge);
        userWalletVO.setIsWithdraw(isWithdraw);
        return userWalletVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transferFail(Long userId, BigDecimal amount) {

        UserWallet wallet = userWalletDao.getByUserId(userId);
        UserWalletDetail walletDetail = new UserWalletDetail();
        walletDetail.setUserId(userId);
        walletDetail.setType(WalletDetailTypeEnum.TRANSFER_FAIL);
        walletDetail.setAmount(amount);
        walletDetail.setCharge(BigDecimal.ZERO);
        walletDetail.setRealAmount(amount);
        walletDetail.setBeforeBalance(wallet.getBalance());
        walletDetail.setAfterBalance(wallet.getBalance().add(walletDetail.getRealAmount()));
        walletDetail.setIsAdd(Boolean.TRUE);
        userWalletDetailDao.insert(walletDetail);

        //账单明细
        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userId);
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(amount);
        expenditureRecord.setType(ExpenditureRecordTypeEnum.TRANSFER_FAIL);
        expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
        expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
        expenditureRecord.setOrderId(0l);
        expenditureRecordDao.insert(expenditureRecord);
        userWalletDao.transferFail(userId, walletDetail.getRealAmount());

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(Long userId, BigDecimal amount, WalletDetailTypeEnum walletDetailType, ExpenditureRecordTypeEnum expenditureRecordType) {
        UserWallet wallet = userWalletDao.getByUserId(userId);
        if (wallet.getBalance().compareTo(amount) < 0) {
            throw new GlobalRunTimeException(ErrorCode.BALANCE_NO_ENOUGH);
        }
        UserWalletDetail walletDetail = new UserWalletDetail();
        walletDetail.setUserId(userId);
        walletDetail.setType(walletDetailType);
        walletDetail.setAmount(amount);
        walletDetail.setCharge(BigDecimal.ZERO);
        walletDetail.setRealAmount(amount);
        walletDetail.setBeforeBalance(wallet.getBalance());
        walletDetail.setAfterBalance(wallet.getBalance().subtract(walletDetail.getRealAmount()));
        walletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetailDao.insert(walletDetail);

        //账单明细
        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userId);
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(amount);
        expenditureRecord.setType(expenditureRecordType);
        expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
        expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
        expenditureRecord.setOrderId(0l);
        expenditureRecordDao.insert(expenditureRecord);
        userWalletDao.transfer(userId, walletDetail.getRealAmount());

    }

    @Override
    public ArrayList<UserWalletVO> getWalletList(UserInfo user) {
        UserWallet userWallet = userWalletDao.getByUserId(user.getId());
        UserWalletVO userWalletVO = BeanUtil.copyProperties(userWallet, UserWalletVO.class);
        userWalletVO.setBalance(userWallet.getBalance().add(userWallet.getPayBalance()).setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setWithdrawBalance(userWallet.getBalance().setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setRedEnvelope(userWallet.getPayBalance().setScale(2, BigDecimal.ROUND_DOWN).toPlainString());
        userWalletVO.setUserBankCount(userBankCardDao.getCountByUserId(user.getId()));
        userWalletVO.setIsSm(user.getIsSm());
        userWalletVO.setUserTel(user.getUserTel());
        userWalletVO.setName("钱包A");
        userWalletVO.setIsEnable(Boolean.TRUE);
        userWalletVO.setType(UserWalletEnum.PLATFORM_WALLET);
        ArrayList<UserWalletVO> list = Lists.newArrayList();
        list.add(userWalletVO);
        return list;
    }

    /**
     * 充值成功(加钱)
     *
     * @param userId  用户Id
     * @param orderNo 订单号
     * @param amount  收益金额
     * @param charge  手续费
     * @param type
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addIncome(Long userId, String orderNo, BigDecimal amount, BigDecimal charge, WalletDetailTypeEnum type, ExpenditureRecordTypeEnum expenditureRecordTypeEnum) {
        addIncome(userId, orderNo, amount, charge, type, expenditureRecordTypeEnum, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPayBalanceIncome(Long userId, String orderNo, BigDecimal amount, BigDecimal charge, WalletDetailTypeEnum type, ExpenditureRecordTypeEnum expenditureRecordTypeEnum, String remark) {
        Assert.notNull(amount, () -> new GlobalRunTimeException(ErrorCode.AMOUNT_ERROR));
        charge = charge == null ? BigDecimal.ZERO : charge;

        if (amount.compareTo(charge) < 1) {
            throw new GlobalRunTimeException(ErrorCode.CHARGE_GT_AMOUNT);
        }
        RLock lock = redisson.getLock(RedisKeyEnum.INCOME_LOCK.getKey() + userId);
        try {
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {


                //用户明细
                UserWallet wallet = userWalletDao.getByUserId(userId);
                UserWalletDetail walletDetail = new UserWalletDetail();
                walletDetail.setUserId(userId);
                walletDetail.setType(type);
                walletDetail.setAmount(amount);
                walletDetail.setCharge(charge);
                walletDetail.setRealAmount(amount.subtract(charge));
                walletDetail.setBeforeBalance(wallet.getPayBalance());
                walletDetail.setAfterBalance(wallet.getPayBalance().add(walletDetail.getRealAmount()));
                walletDetail.setIsAdd(Boolean.TRUE);
                walletDetail.setRemark(type.getDescription());
                walletDetail.setBalanceType(UserBalanceTypeEnum.PAY_BALANCE);
                userWalletDetailDao.insert(walletDetail);
                userWalletDao.addPayBalance(userId, walletDetail.getRealAmount());

                //账单明细
                ExpenditureRecord expenditureRecord = new ExpenditureRecord();
                expenditureRecord.setUserId(userId);
                expenditureRecord.setAmount(amount);
                expenditureRecord.setCharge(charge);
                expenditureRecord.setRealAmount(amount.subtract(charge));
                expenditureRecord.setType(expenditureRecordTypeEnum);
                expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
                expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
                expenditureRecord.setOrderId(0l);
                if (!BeanUtil.isEmpty(type)) {
                    expenditureRecord.setRemark(type.getDescription());
                }
                if (StrUtil.isNotBlank(remark)) {
                    expenditureRecord.setRemark(remark);
                }
                expenditureRecordDao.insert(expenditureRecord);
            } else {
                throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
        } finally {
            lock.unlock();
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addIncome(Long userId, String orderNo, BigDecimal amount, BigDecimal charge, WalletDetailTypeEnum type, ExpenditureRecordTypeEnum expenditureRecordTypeEnum, String remark) {
        Assert.notNull(amount, () -> new GlobalRunTimeException(ErrorCode.AMOUNT_ERROR));
        charge = charge == null ? BigDecimal.ZERO : charge;

        if (amount.compareTo(charge) < 1) {
            throw new GlobalRunTimeException(ErrorCode.CHARGE_GT_AMOUNT);
        }
        RLock lock = redisson.getLock(RedisKeyEnum.INCOME_LOCK.getKey() + userId);
        try {
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {
                if (expenditureRecordTypeEnum == ExpenditureRecordTypeEnum.RECHARGE || type == WalletDetailTypeEnum.RECHARGE) {
                    //充值记录
                    DepositWithdrawalRecord depositWithdrawalRecord = new DepositWithdrawalRecord();
                    depositWithdrawalRecord.setUserId(userId);
                    depositWithdrawalRecord.setType(DepositWithdrawalRecordTypeEnum.RECHARGE);
                    depositWithdrawalRecord.setStatus(DepositWithdrawalRecordStatusEnum.SUCCESS);
                    depositWithdrawalRecord.setAmount(amount);
                    depositWithdrawalRecord.setCharge(charge);
                    depositWithdrawalRecord.setRealAmount(amount.subtract(charge));
                    depositWithdrawalRecord.setPayStatus(DepositWithdrawalRecordPayStatusEnum.SUCCESS);
                    depositWithdrawalRecord.setOrderId(0L);
                    depositWithdrawalRecord.setOrderNo(orderNo);
                    depositWithdrawalRecord.insert();
                }

                //用户明细
                UserWallet wallet = userWalletDao.getByUserId(userId);
                UserWalletDetail walletDetail = new UserWalletDetail();
                walletDetail.setUserId(userId);
                walletDetail.setType(type);
                walletDetail.setAmount(amount);
                walletDetail.setCharge(charge);
                walletDetail.setRealAmount(amount.subtract(charge));
                walletDetail.setBeforeBalance(wallet.getBalance());
                walletDetail.setAfterBalance(wallet.getBalance().add(walletDetail.getRealAmount()));
                walletDetail.setIsAdd(Boolean.TRUE);
                walletDetail.setRemark(type.getDescription());
                userWalletDetailDao.insert(walletDetail);
                userWalletDao.recharge(userId, walletDetail.getRealAmount());

                //账单明细
                ExpenditureRecord expenditureRecord = new ExpenditureRecord();
                expenditureRecord.setUserId(userId);
                expenditureRecord.setAmount(amount);
                expenditureRecord.setCharge(charge);
                expenditureRecord.setRealAmount(amount.subtract(charge));
                expenditureRecord.setType(expenditureRecordTypeEnum);
                expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
                expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
                expenditureRecord.setOrderId(0l);
                if (!BeanUtil.isEmpty(type)) {
                    expenditureRecord.setRemark(type.getDescription());
                }
                if (StrUtil.isNotBlank(remark)) {
                    expenditureRecord.setRemark(remark);
                }
                expenditureRecordDao.insert(expenditureRecord);
            } else {
                throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public void addSplitIncome(Long userId, String orderNo, BigDecimal amount, WalletDetailTypeEnum type, ExpenditureRecordTypeEnum expenditureRecordTypeEnum, String remark) {
        Assert.notNull(amount, () -> new GlobalRunTimeException(ErrorCode.AMOUNT_ERROR));
        BigDecimal charge = BigDecimal.ZERO;

        if (amount.compareTo(charge) < 1) {
            throw new GlobalRunTimeException(ErrorCode.CHARGE_GT_AMOUNT);
        }
        RLock lock = redisson.getLock(RedisKeyEnum.INCOME_LOCK.getKey() + userId);
        try {
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {

                //用户明细
                UserWallet wallet = userWalletDao.getByUserId(userId);
                UserWalletDetail walletDetail = new UserWalletDetail();
                walletDetail.setUserId(userId);
                walletDetail.setType(type);
                walletDetail.setAmount(amount);
                walletDetail.setCharge(charge);
                walletDetail.setRealAmount(amount.subtract(charge));
                walletDetail.setBeforeBalance(wallet.getPayBalance());
                walletDetail.setAfterBalance(wallet.getPayBalance().add(walletDetail.getRealAmount()));
                walletDetail.setIsAdd(Boolean.TRUE);
                walletDetail.setRemark(type.getDescription());
                walletDetail.setBalanceType(UserBalanceTypeEnum.PAY_BALANCE);
                userWalletDetailDao.insert(walletDetail);
                userWalletDao.addPayBalance(userId, walletDetail.getRealAmount());

                //账单明细
                ExpenditureRecord expenditureRecord = new ExpenditureRecord();
                expenditureRecord.setUserId(userId);
                expenditureRecord.setAmount(amount);
                expenditureRecord.setCharge(charge);
                expenditureRecord.setRealAmount(amount.subtract(charge));
                expenditureRecord.setType(expenditureRecordTypeEnum);
                expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
                expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
                expenditureRecord.setOrderId(0l);
                if (!BeanUtil.isEmpty(type)) {
                    expenditureRecord.setRemark(type.getDescription());
                }
                if (StrUtil.isNotBlank(remark)) {
                    expenditureRecord.setRemark(remark);
                }
                expenditureRecordDao.insert(expenditureRecord);
            } else {
                throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
            }
        } catch (InterruptedException e) {
            throw new GlobalRunTimeException(ErrorCode.LATER_TRY);
        } finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addIncomeRemit(Long userId, String orderNo, BigDecimal amount, BigDecimal charge, BigDecimal gas, WalletDetailTypeEnum type, ExpenditureRecordTypeEnum expenditureRecordTypeEnum) {
        Assert.notNull(amount, () -> new GlobalRunTimeException(ErrorCode.AMOUNT_ERROR));
        charge = charge == null ? BigDecimal.ZERO : charge;

        if (amount.compareTo(charge) < 1) {
            throw new GlobalRunTimeException(ErrorCode.CHARGE_GT_AMOUNT);
        }

        try {
            if (expenditureRecordTypeEnum == ExpenditureRecordTypeEnum.RECHARGE || type == WalletDetailTypeEnum.RECHARGE) {
                //充值记录
                DepositWithdrawalRecord depositWithdrawalRecord = new DepositWithdrawalRecord();
                depositWithdrawalRecord.setUserId(userId);
                depositWithdrawalRecord.setType(DepositWithdrawalRecordTypeEnum.RECHARGE);
                depositWithdrawalRecord.setStatus(DepositWithdrawalRecordStatusEnum.SUCCESS);
                depositWithdrawalRecord.setAmount(amount);
                depositWithdrawalRecord.setCharge(charge);
                depositWithdrawalRecord.setRealAmount(amount.subtract(charge));
                depositWithdrawalRecord.setPayStatus(DepositWithdrawalRecordPayStatusEnum.SUCCESS);
                depositWithdrawalRecord.setOrderId(0L);
                depositWithdrawalRecord.setOrderNo(orderNo);
                depositWithdrawalRecord.insert();
            }
            //用户明细
            UserWallet wallet = userWalletDao.getByUserId(userId);
            UserWalletDetail walletDetail = new UserWalletDetail();
            walletDetail.setUserId(userId);
            walletDetail.setType(type);
            walletDetail.setAmount(amount);
            walletDetail.setCharge(charge);
            walletDetail.setRealAmount(amount.subtract(charge).subtract(gas));
            walletDetail.setBeforeBalance(wallet.getBalance());
            walletDetail.setAfterBalance(wallet.getBalance().add(walletDetail.getRealAmount()));
            walletDetail.setIsAdd(Boolean.TRUE);
            userWalletDetailDao.insert(walletDetail);
            userWalletDao.recharge(userId, walletDetail.getRealAmount());

            //账单明细
            ExpenditureRecord expenditureRecord = new ExpenditureRecord();
            expenditureRecord.setUserId(userId);
            expenditureRecord.setAmount(amount);
            expenditureRecord.setCharge(charge.add(gas));
            expenditureRecord.setRealAmount(amount.subtract(charge).subtract(gas));
            expenditureRecord.setType(expenditureRecordTypeEnum);
            expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
            expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
            expenditureRecord.setOrderId(0l);
            expenditureRecordDao.insert(expenditureRecord);
        } finally {
        }
    }


    @Override
    public boolean subBalance(UserWallet userWallet, BigDecimal productPrice, Long orderId, WalletDetailTypeEnum walletDetailTypeEnum, UserBalanceTypeEnum userBalanceTypeEnum) {
        ExpenditureRecordTypeEnum type = ExpenditureRecordTypeEnum.EXPENDITURE;
        BigDecimal balance = BigDecimal.ZERO;
        boolean flag = Boolean.FALSE;
        switch (userBalanceTypeEnum) {
            case BALANCE:
                balance = userWallet.getBalance();
                flag = userWalletDao.subBalance(userWallet.getUserId(), productPrice);
                break;
            case PAY_BALANCE:
                balance = userWallet.getPayBalance();
                flag = userWalletDao.subPayBalance(userWallet.getUserId(), productPrice);

                type = ExpenditureRecordTypeEnum.RED_PACKET_DEDUCTION;
                break;
            case WISH_BALANCE:
                balance = userWallet.getWishBalance();
                flag = userWalletDao.subWishBalance(userWallet.getUserId(), productPrice);
                type = ExpenditureRecordTypeEnum.WISH_BALANCE_DEDUCTION;
                break;
        }
        if (!flag) {
            throw new GlobalRunTimeException(ErrorCode.PAYMENT_FAILED);
        }
        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userWallet.getUserId());
        userWalletDetail.setType(walletDetailTypeEnum);
        userWalletDetail.setAmount(productPrice);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(productPrice);
        userWalletDetail.setBeforeBalance(balance);
        userWalletDetail.setAfterBalance(balance.subtract(productPrice));
        userWalletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetail.setBalanceType(userBalanceTypeEnum);
        userWalletDetailDao.insert(userWalletDetail);

        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userWallet.getUserId());
        expenditureRecord.setAmount(productPrice);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(BigDecimal.ZERO);
        expenditureRecord.setType(type);
        expenditureRecord.setBeforeBalance(userWallet.getBalance());
        expenditureRecord.setAfterBalance(userWallet.getBalance().subtract(productPrice));
        expenditureRecord.setOrderId(orderId);
        expenditureRecordDao.insert(expenditureRecord);


        return flag;
    }

    @Override
    public boolean otherSubBalance(UserWallet userWallet, BigDecimal productPrice, Long orderId, WalletDetailTypeEnum walletDetailTypeEnum, UserBalanceTypeEnum userBalanceTypeEnum) {
        ExpenditureRecordTypeEnum type = ExpenditureRecordTypeEnum.EXPENDITURE;
        BigDecimal balance = BigDecimal.ZERO;
        boolean flag = Boolean.FALSE;
        switch (userBalanceTypeEnum) {
            case BALANCE:
                balance = userWallet.getBalance();
                flag = userWalletDao.subBalance(userWallet.getUserId(), productPrice);
                break;
            case PAY_BALANCE:
                balance = userWallet.getPayBalance();
                flag = userWalletDao.subPayBalance(userWallet.getUserId(), productPrice);

                type = ExpenditureRecordTypeEnum.RED_PACKET_DEDUCTION;
                break;
            case WISH_BALANCE:
                balance = userWallet.getWishBalance();
                flag = userWalletDao.subWishBalance(userWallet.getUserId(), productPrice);
                type = ExpenditureRecordTypeEnum.WISH_BALANCE_DEDUCTION;
                break;
        }
        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userWallet.getUserId());
        userWalletDetail.setType(walletDetailTypeEnum);
        userWalletDetail.setAmount(productPrice);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(productPrice);
        userWalletDetail.setBeforeBalance(balance);
        userWalletDetail.setAfterBalance(balance.subtract(productPrice));
        userWalletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetail.setBalanceType(userBalanceTypeEnum);
        userWalletDetailDao.insert(userWalletDetail);

        if (!flag) {
            throw new GlobalRunTimeException(ErrorCode.PAYMENT_FAILED);
        }
        return flag;
    }

    @Override
    public boolean subBalance(UserWallet userWallet, BigDecimal productPrice, Long orderId, WalletDetailTypeEnum walletDetailTypeEnum, UserBalanceTypeEnum userBalanceTypeEnum, String remark) {
        BigDecimal balance = BigDecimal.ZERO;
        if (userBalanceTypeEnum == UserBalanceTypeEnum.BALANCE) {
            balance = userWallet.getBalance();
        } else if (userBalanceTypeEnum == UserBalanceTypeEnum.PAY_BALANCE) {
            balance = userWallet.getPayBalance();
        }

        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userWallet.getUserId());
        userWalletDetail.setType(walletDetailTypeEnum);
        userWalletDetail.setAmount(productPrice);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(productPrice);
        userWalletDetail.setBeforeBalance(balance);
        userWalletDetail.setAfterBalance(balance.subtract(productPrice));
        userWalletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetail.setBalanceType(userBalanceTypeEnum);
        userWalletDetailDao.insert(userWalletDetail);

        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userWallet.getUserId());
        expenditureRecord.setAmount(productPrice);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(BigDecimal.ZERO);
        if (userBalanceTypeEnum == UserBalanceTypeEnum.PAY_BALANCE) {
            expenditureRecord.setType(ExpenditureRecordTypeEnum.RED_PACKET_DEDUCTION);
            expenditureRecord.setBeforeBalance(userWallet.getPayBalance());
            expenditureRecord.setAfterBalance(userWallet.getPayBalance().subtract(productPrice));
        } else {
            expenditureRecord.setType(ExpenditureRecordTypeEnum.EXPENDITURE);
            expenditureRecord.setBeforeBalance(userWallet.getBalance());
            expenditureRecord.setAfterBalance(userWallet.getBalance().subtract(productPrice));
        }
        expenditureRecord.setOrderId(orderId);
        expenditureRecord.setRemark(remark);
        expenditureRecordDao.insert(expenditureRecord);

        boolean falg = Boolean.FALSE;
        if (userBalanceTypeEnum == UserBalanceTypeEnum.BALANCE) {
            falg = userWalletDao.subBalance(userWallet.getUserId(), productPrice);
        } else if (userBalanceTypeEnum == UserBalanceTypeEnum.PAY_BALANCE) {
            falg = userWalletDao.subPayBalance(userWallet.getUserId(), productPrice);
        }

        if (!falg) {
            throw new GlobalRunTimeException(ErrorCode.PAYMENT_FAILED);
        }
        return falg;
    }

    @Override
    public boolean marginDeduction(UserWallet userWallet, BigDecimal amount, Long orderId, WalletDetailTypeEnum walletDetailTypeEnum, ExpenditureRecordTypeEnum expenditureRecordTypeEnum, String remark) {
        BigDecimal balance = userWallet.getBalance();

        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userWallet.getUserId());
        userWalletDetail.setType(walletDetailTypeEnum);
        userWalletDetail.setAmount(amount);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(amount);
        userWalletDetail.setBeforeBalance(balance);
        userWalletDetail.setAfterBalance(balance.subtract(amount));
        userWalletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetailDao.insert(userWalletDetail);

        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userWallet.getUserId());
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(BigDecimal.ZERO);
        expenditureRecord.setType(ExpenditureRecordTypeEnum.DEPOSIT_PAYMENT);
        expenditureRecord.setBeforeBalance(userWallet.getBalance());
        expenditureRecord.setAfterBalance(userWallet.getBalance().subtract(amount));
        expenditureRecord.setOrderId(orderId);
        expenditureRecord.setRemark(remark);
        expenditureRecordDao.insert(expenditureRecord);
        boolean falg = userWalletDao.subBalance(userWallet.getUserId(), amount);
        if (!falg) {
            throw new GlobalRunTimeException(ErrorCode.PAYMENT_FAILED);
        }
        return falg;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void operateUserWallet(String userTel, Boolean isType, BigDecimal amount, String remark, UserBalanceTypeEnum userBalanceType) {
        UserInfo oneByUserTel = userInfoDao.getOneByUserTel(userTel);
        UserWallet userWallet = userWalletDao.getByUserId(oneByUserTel.getId());
        BigDecimal balance = BigDecimal.ZERO;
        if (userBalanceType == UserBalanceTypeEnum.BALANCE) {
            balance = userWallet.getBalance();

        } else if (userBalanceType == UserBalanceTypeEnum.PAY_BALANCE) {
            balance = userWallet.getPayBalance();
        }

        Assert.notNull(oneByUserTel, () -> new GlobalRunTimeException(ErrorCode.ACCOUNT_NOT_EXIST));
        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(oneByUserTel.getId());
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(amount);
        expenditureRecord.setBeforeBalance(balance);
        expenditureRecord.setRemark(remark);

        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(oneByUserTel.getId());
        userWalletDetail.setAmount(amount);
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(amount);
        userWalletDetail.setBeforeBalance(balance);
        userWalletDetail.setBalanceType(userBalanceType);
        Boolean flag = Boolean.FALSE;
        if (isType) {
            expenditureRecord.setType(ExpenditureRecordTypeEnum.BACKSTAGE_ADD);
            if (userBalanceType == UserBalanceTypeEnum.BALANCE) {
                Boolean aBoolean = userWalletDao.addBalance(oneByUserTel.getId(), amount);
                if (!aBoolean) {
                    throw new GlobalRunTimeException(ErrorCode.FAILED_TO_ADD_MONEY);
                }

            } else if (userBalanceType == UserBalanceTypeEnum.PAY_BALANCE) {
                Boolean aBoolean = userWalletDao.addPayBalance(oneByUserTel.getId(), amount);
                expenditureRecord.setType(ExpenditureRecordTypeEnum.RED_PACKET);

                if (!aBoolean) {
                    throw new GlobalRunTimeException(ErrorCode.FAILED_TO_ADD_MONEY);
                }
            }

            expenditureRecord.setAfterBalance(userWallet.getBalance().add(amount));
            userWalletDetail.setType(WalletDetailTypeEnum.BACKSTAGE_ADD);
            userWalletDetail.setAfterBalance(userWallet.getBalance().add(amount));
            userWalletDetail.setIsAdd(Boolean.TRUE);
        } else {
            if (userBalanceType == UserBalanceTypeEnum.BALANCE) {
                Boolean aBoolean = userWalletDao.subBalance(oneByUserTel.getId(), amount);
                if (!aBoolean) {
                    throw new GlobalRunTimeException(ErrorCode.DEDUCTION_FAILED);
                }
            } else if (userBalanceType == UserBalanceTypeEnum.PAY_BALANCE) {
                Boolean aBoolean = userWalletDao.subPayBalance(oneByUserTel.getId(), amount);
                if (!aBoolean) {
                    throw new GlobalRunTimeException(ErrorCode.DEDUCTION_FAILED);
                }
            }

            expenditureRecord.setType(ExpenditureRecordTypeEnum.BACKSTAGE_SUB);
            expenditureRecord.setAfterBalance(userWallet.getBalance().subtract(amount));
            userWalletDetail.setType(WalletDetailTypeEnum.BACKSTAGE_SUB);
            userWalletDetail.setAfterBalance(userWallet.getBalance().subtract(amount));
            userWalletDetail.setIsAdd(Boolean.FALSE);
        }

        expenditureRecordDao.insert(expenditureRecord);
        userWalletDetailDao.insert(userWalletDetail);
    }

    @Override
    public Page<UserWalletListVO> userWalletList(String userTel, int pageNo, int pageSize) {
        return userWalletDao.userWalletList(userTel, pageNo, pageSize);
    }

    @Override
    public GetWithdrawDetailsVO getWithdrawDetails(UserInfo user, WalletChannelEnum channel) {
        UserWallet userWallet = userWalletDao.getByUserId(user.getId());
        BigDecimal balance = userWallet.getBalance();
        //提现手续费(百分比)
        String withdrawalFeeString = StrUtil.EMPTY;
        GetWithdrawDetailsVO getWithdrawDetailsVO = new GetWithdrawDetailsVO();
        getWithdrawDetailsVO.setUserTel(user.getUserTel());
        switch (channel) {
            case SAND:
                withdrawalFeeString = staticDataDao.getByType("sand_withdrawal_fee").getValue();
                break;
//            case HF: //三方钱包不需要
//                withdrawalFeeString = staticDataDao.getByType("withdrawal_fee").getValue();
//                break;
            case LL:
                withdrawalFeeString = staticDataDao.getByType("ll_withdrawal_fee").getValue();
                LlUserExt llUserExt = llUserExtDao.getByUserId(user.getId());
                if (ObjectUtil.isNotNull(llUserExt) && llUserExt.getStatus() == AccountStatusEnum.SUCCESS) {
                    getWithdrawDetailsVO.setUserTel(llUserExt.getRegPhone());
                }
                break;
            case HNA:
                withdrawalFeeString = staticDataDao.getByType("withdrawal_fee").getValue();
                break;
            default:
                throw new GlobalRunTimeException("渠道错误");
        }

        //最低手续费(固定额度)
        String minimumWithdrawalFeeString = staticDataDao.getByType("minimum_withdrawal_fee").getValue();
        //最小起提金额
        String minimumWithdrawalAmountString = staticDataDao.getByType("minimum_withdrawal_amount").getValue();
        String withdrawalFee = new BigDecimal(withdrawalFeeString).multiply(new BigDecimal("100")).stripTrailingZeros().toPlainString();
        getWithdrawDetailsVO.setBalance(balance.stripTrailingZeros().toPlainString());
        getWithdrawDetailsVO.setWithdrawalFee(withdrawalFee);
        getWithdrawDetailsVO.setLlWithdrawalFee(withdrawalFee);
        getWithdrawDetailsVO.setMinimumWithdrawalFee(minimumWithdrawalFeeString);
        getWithdrawDetailsVO.setMinimumWithdrawalAmount(minimumWithdrawalAmountString);
        Boolean byUserIdAndStatus = depositWithdrawalRecordDao.getByUserIdExists(user.getId());
        getWithdrawDetailsVO.setWithdrawal(byUserIdAndStatus);
        return getWithdrawDetailsVO;

    }

    @Override
    public GetWithdrawFeeVO getWithdrawAmount(String amount, Integer type, WalletChannelEnum channel) {
        //起提金额
        String minimumWithdrawalAmount = staticDataDao.getByType("minimum_withdrawal_amount").getValue();
        BigDecimal bigDecimal = new BigDecimal(amount);
        if (bigDecimal.compareTo(new BigDecimal(minimumWithdrawalAmount)) == -1) {
            throw new GlobalRunTimeException(ErrorCode.AMOUNT_ERROR);
        }

        BigDecimal fee = BigDecimal.ZERO;
        if (StrUtil.isNotBlank(amount)) {
            fee = getWithdrawalFee(bigDecimal, type, channel);
        }
        GetWithdrawFeeVO getWithdrawFeeVO = new GetWithdrawFeeVO();
        getWithdrawFeeVO.setAmount(bigDecimal.subtract(fee));
        return getWithdrawFeeVO;
    }

    @Override
    public List<OperateUserWalletBatchListVO> operateUserWalletBatchList(List<OperateUserWalletBatchAmountDTO> userMoney) {
        return userWalletDao.operateUserWalletBatchList(userMoney.stream().map(OperateUserWalletBatchAmountDTO::getUserTel).collect(Collectors.toList()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public MarginPaymentVO marginPayment(MarginPaymentDTO marginPaymentDTO) {
        // 获取保证金额度
        String marginPayment = staticDataDao.getByType("cash_deposit").getValue();
        // 用于余额扣款以及日志记录
        UserWallet userWallet = userWalletDao.getByUserId(marginPaymentDTO.getUserId());
        UserInfo userInfo = userInfoDao.getById(marginPaymentDTO.getUserId());
        if (!userInfo.getTransactionPassword().equals(marginPaymentDTO.getDealPwd())) {
            throw new GlobalRunTimeException("支付密码错误");
        }
        boolean marginDeductionBoolean = marginDeduction(userWallet, Convert.toBigDecimal(marginPayment), marginPaymentDTO.getOrderId(), WalletDetailTypeEnum.DEPOSIT_PAYMENT, ExpenditureRecordTypeEnum.DEPOSIT_PAYMENT, "保证金扣款");
        MarginPaymentVO marginPaymentVO = new MarginPaymentVO();
        marginPaymentVO.setPaymentAmount(Convert.toBigDecimal(marginPayment));
        marginPaymentVO.setDaoId(marginPaymentDTO.getDaoId());
        marginPaymentVO.setUserId(marginPaymentDTO.getUserId());
        marginPaymentVO.setTimeOfPayment(new Date());
        marginPaymentVO.setTheResultOfThePayment(marginDeductionBoolean);
        return marginPaymentVO;
    }

    @Override
    public DepositRefundVO depositRefund(DepositRefundDTO depositRefundDTO) {
        addIncome(depositRefundDTO.getUserId(), Convert.toStr(depositRefundDTO.getOrderId()), depositRefundDTO.getEarnestMoney(), BigDecimal.ZERO, WalletDetailTypeEnum.DEPOSIT_RELEASED, ExpenditureRecordTypeEnum.DEPOSIT_RELEASED);
        DepositRefundVO depositRefundVO = new DepositRefundVO();
        depositRefundVO.setRefundAmount(depositRefundDTO.getEarnestMoney());
        depositRefundVO.setDaoId(depositRefundDTO.getDaoId());
        depositRefundVO.setUserId(depositRefundDTO.getUserId());
        depositRefundVO.setRefundTime(new Date());
        depositRefundVO.setRefundResult(Boolean.TRUE);
        return depositRefundVO;
    }

    @Override
    public boolean addAmountByUserId(Long userId, BigDecimal amount, UserBalanceTypeEnum balanceType, String remark, WalletDetailTypeEnum type) {
        //用户明细
        UserWallet wallet = userWalletDao.getByUserId(userId);
        UserWalletDetail walletDetail = new UserWalletDetail();
        walletDetail.setUserId(userId);
        walletDetail.setType(type);
        walletDetail.setAmount(amount);
        walletDetail.setCharge(BigDecimal.ZERO);
        walletDetail.setRealAmount(amount.subtract(BigDecimal.ZERO));
        walletDetail.setBeforeBalance(wallet.getBalance());
        walletDetail.setAfterBalance(wallet.getBalance().add(walletDetail.getRealAmount()));
        walletDetail.setIsAdd(Boolean.TRUE);
        walletDetail.setRemark(remark);
        userWalletDetailDao.insert(walletDetail);
        Boolean falg = userWalletDao.addPayBalance(userId, walletDetail.getRealAmount());

        //账单明细
        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userId);
        expenditureRecord.setRemark(remark);
        expenditureRecord.setAmount(amount);
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(amount.subtract(BigDecimal.ZERO));
        expenditureRecord.setType(ExpenditureRecordTypeEnum.RED_PACKET);
        expenditureRecord.setBeforeBalance(walletDetail.getBeforeBalance());
        expenditureRecord.setAfterBalance(walletDetail.getAfterBalance());
        expenditureRecord.setRemark(remark);
        expenditureRecord.setOrderId(0l);
        expenditureRecordDao.insert(expenditureRecord);

        return falg;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void mapShareProfit(MetaMapSettle metaMapSettle) {
        UserWallet upUserWallet = userWalletDao.getByUserId(metaMapSettle.getEarningsUserId());

        // 把返现金额给用户
        userWalletDao.addBalance(metaMapSettle.getEarningsUserId(), metaMapSettle.getQuota());

        WalletDetailTypeEnum walletDetailTypeEnum = WalletDetailTypeEnum.COPYRIGHT;

        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(metaMapSettle.getEarningsUserId());
        userWalletDetail.setType(walletDetailTypeEnum);
        userWalletDetail.setBalanceType(UserBalanceTypeEnum.BALANCE);
        userWalletDetail.setAmount(metaMapSettle.getQuota());
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(metaMapSettle.getQuota());
        userWalletDetail.setAfterBalance(upUserWallet.getPayBalance().add(metaMapSettle.getQuota()));
        userWalletDetail.setBeforeBalance(upUserWallet.getPayBalance());
        userWalletDetail.setIsAdd(Boolean.TRUE);
        userWalletDetail.setRemark(walletDetailTypeEnum.getDescription());
        userWalletDetailDao.insert(userWalletDetail);

        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setRemark(metaMapSettle.getMetaMap());
        expenditureRecord.setUserId(metaMapSettle.getEarningsUserId());
        expenditureRecord.setAmount(metaMapSettle.getQuota());
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(metaMapSettle.getQuota());
        expenditureRecord.setType(ExpenditureRecordTypeEnum.META_MAP);
        expenditureRecord.setBeforeBalance(upUserWallet.getBalance());
        expenditureRecord.setAfterBalance(upUserWallet.getBalance().add(metaMapSettle.getQuota()));
        expenditureRecordDao.insert(expenditureRecord);

        UserIncomeRecord userIncomeRecord = new UserIncomeRecord();
        userIncomeRecord.setAmount(metaMapSettle.getQuota());
        userIncomeRecord.setUserId(metaMapSettle.getEarningsUserId());
        userIncomeRecord.setIncomeType(IncomeTypeEnum.COPYRIGHT_INCOME);
        String incomeHierarchyName = "";
        switch (metaMapSettle.getSourceType()) {
            case FIRST_ORDER:
                incomeHierarchyName = "首发购买";
                break;
            case SECOND_ORDER:
                incomeHierarchyName = "寄售手续费";
                break;
            case PROP_ORDER:
                incomeHierarchyName = "道具手续费";
                break;
            case SHOP:
                incomeHierarchyName = "卷轴商店手续费";
                break;
            default:
                incomeHierarchyName = "未知来源收益";
        }
        userIncomeRecord.setIncomeTypeName(incomeHierarchyName);
        userIncomeRecord.setIncomeHierarchy(IncomeHierarchyEnum.COPYRIGHT);
        userIncomeRecord.setIncomeHierarchyName(IncomeHierarchyEnum.COPYRIGHT.getDescription());
        userIncomeRecord.setOrderNo(metaMapSettle.getOrderNo());
        userIncomeRecord.setSourceUserId(metaMapSettle.getBuyUserId());
        userIncomeRecord.setIncomeUserNum(Convert.toStr(metaMapSettle.getParticipation()));
        userIncomeRecord.setDescribe(metaMapSettle.getMetaMap());
        userIncomeRecord.insert();

        // 结算完成
        if (!metaMapSettleDao.settleAnAccountSuccess(metaMapSettle.getId())) {
            throw new GlobalRunTimeException("结算地图状态更新失败");
        }
    }

    /**
     * 获取用户余额
     *
     * @param userId
     * @return
     */
    @Override
    public MallUserWalletBalance getMallUserBalance(Long userId) {
        UserInfo userInfo = userInfoDao.getById(userId);
        if (BeanUtil.isEmpty(userInfo)) {
            throw new GlobalRunTimeException(ErrorCode.THE_USER_DOES_NOT_EXIST);
        }
        MallUserWalletBalance mallUserWalletBalance=new MallUserWalletBalance();
        mallUserWalletBalance.setBalance(userWalletDao.getMallUserBalance(userId));
        return mallUserWalletBalance;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean shoppingAllowanceControls(MallDeductMoneyDto mallDeductMoneyDto) {
        UserWallet userWallet = userWalletDao.getByUserId(mallDeductMoneyDto.getId());
        Boolean flag;
        if (!mallDeductMoneyDto.getIsAdd()) {
            flag = userWalletDao.subWishBalance(mallDeductMoneyDto.getId(), mallDeductMoneyDto.getAmount());
        }else {
            flag = userWalletDao.addWishBalance(mallDeductMoneyDto.getId(), mallDeductMoneyDto.getAmount());
        }
        if (!flag) {
            throw new GlobalRunTimeException(ErrorCode.PAYMENT_FAILED);
        }
        UserWalletDetail userWalletDetail = new UserWalletDetail();
        userWalletDetail.setUserId(userWallet.getUserId());
        userWalletDetail.setType(mallDeductMoneyDto.getWalletDetailTypeEnum());
        userWalletDetail.setAmount(mallDeductMoneyDto.getAmount());
        userWalletDetail.setCharge(BigDecimal.ZERO);
        userWalletDetail.setRealAmount(mallDeductMoneyDto.getAmount());
        userWalletDetail.setBeforeBalance(userWallet.getWishBalance());
        userWalletDetail.setAfterBalance(userWallet.getWishBalance().subtract(mallDeductMoneyDto.getAmount()));
        userWalletDetail.setIsAdd(Boolean.FALSE);
        userWalletDetail.setBalanceType(mallDeductMoneyDto.getUserBalanceTypeEnum());
        userWalletDetailDao.insert(userWalletDetail);

        ExpenditureRecord expenditureRecord = new ExpenditureRecord();
        expenditureRecord.setUserId(userWallet.getUserId());
        expenditureRecord.setAmount(mallDeductMoneyDto.getAmount());
        expenditureRecord.setCharge(BigDecimal.ZERO);
        expenditureRecord.setRealAmount(BigDecimal.ZERO);
        expenditureRecord.setType(mallDeductMoneyDto.getType());
        expenditureRecord.setBeforeBalance(userWallet.getBalance());
        expenditureRecord.setAfterBalance(userWallet.getBalance().subtract(mallDeductMoneyDto.getAmount()));
        expenditureRecord.setOrderId(mallDeductMoneyDto.getOrderId());
        expenditureRecordDao.insert(expenditureRecord);
        return Boolean.TRUE;
    }

    /**
     * 获取手续费
     * <p>
     * 如果手续费的百分比结果 小于 固定额度  手续费就是
     *
     * @param amount
     * @return
     */
    private BigDecimal getWithdrawalFee(BigDecimal amount, Integer type, WalletChannelEnum channel) {
        String withdrawalFee = null;
        if (channel == null) {
            withdrawalFee = staticDataDao.getByType("withdrawal_fee").getValue();
            if (type == 1) {
                withdrawalFee = "0.015";
            }
        } else {
            switch (channel) {
                case SAND:
                    withdrawalFee = staticDataDao.getByType("sand_withdrawal_fee").getValue();
                    break;
                case LL:
                    withdrawalFee = staticDataDao.getByType("ll_withdrawal_fee").getValue();
                    break;
                case HNA:
                    withdrawalFee = staticDataDao.getByType("withdrawal_fee").getValue();
                    break;
            }
        }
        //如果手续费小于固定额度  就等于固定额度
        BigDecimal charge = new BigDecimal(withdrawalFee).multiply(amount).setScale(2, BigDecimal.ROUND_DOWN);
        String minimumWithdrawalFeeString = staticDataDao.getByType("minimum_withdrawal_fee").getValue();
        BigDecimal minimumWithdrawalFee = new BigDecimal(minimumWithdrawalFeeString);
        if (charge.compareTo(minimumWithdrawalFee) == -1) {
            return minimumWithdrawalFee;
        }
        // 确定用户是否有指定的特权藏品,特权藏品需要计算获取对应的特权.如果没有就算了.
        UserInfo userInfo = userInfoDao.getById(UserPool.getUser().getId());
        QueryWrapper<Privilege> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("level", userInfo.getPrivilegeLevel());
        Privilege privilege = (Privilege) new Privilege().selectOne(queryWrapper);
        if (!BeanUtil.isEmpty(privilege)) {
            // 如果bean对象不为空,计算对应的折扣
            if (privilege.getWithdrawServerChargeDiscount() != null && privilege.getWithdrawServerChargeDiscount().compareTo(BigDecimal.ZERO) == 1) {
                return charge.multiply(privilege.getWithdrawServerChargeDiscount()).setScale(2, BigDecimal.ROUND_DOWN);
            }
        }
        return charge;
    }

}